/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved.
 */

#ifndef shader_str_h
#define shader_str_h

const char* defaultVs =
    "#version 300 es\n"
    "in vec4 a_position;\n"
    "in vec2 a_texcoord;\n"
    "out vec2 v_texcoord;\n"
    "void main() {\n"
    "  gl_Position = a_position;\n"
    "  v_texcoord = a_texcoord;\n"
    "}\n";

const char* defaultFs =
    "#version 300 es\n"
    "precision lowp float;\n"
    "in vec2 v_texcoord;\n"
    "uniform sampler2D u_texture;\n"
    "layout(location=0) out vec4 fragColor;\n"
    "void main() {\n"
    "  fragColor = texture(u_texture, v_texcoord);\n"
    "}\n";

const char* brightFs =
    "#version 300 es\n"
    "precision lowp float;\n"
    "in vec2 v_texcoord;\n"
    "uniform sampler2D u_texture;\n"
    "uniform float brightness;\n"
    "layout(location=0) out vec4 fragColor;\n"
    "void main() {\n"
    "  vec4 textureColor = texture(u_texture, v_texcoord);\n"
    "  fragColor = vec4((textureColor.rgb + vec3(brightness)), textureColor.w);\n"
    "}\n";

const char* contrastFs =
    "#version 300 es\n"
    "precision lowp float;\n"
    "in vec2 v_texcoord;\n"
    "uniform sampler2D u_texture;\n"
    "uniform float contrast;\n"
    "layout(location=0) out vec4 fragColor;\n"
    "void main() {\n"
    "  vec4 textureColor = texture(u_texture, v_texcoord);\n"
    "  fragColor = vec4(((textureColor.rgb - vec3(0.5)) * contrast + vec3(0.5)), textureColor.w);\n"
    "}\n";

const char* grayscaleFs =
    "#version 300 es\n"
    "precision lowp float;\n"
    "in vec2 v_texcoord;\n"
    "uniform sampler2D u_texture;\n"
    "const vec3 W = vec3(0.2125, 0.7154, 0.0721);\n"
    "layout(location=0) out vec4 fragColor;\n"
    "void main()\n"
    "{\n"
    "   vec4 texColor = texture(u_texture, v_texcoord);\n"
    "   float luminance = dot(texColor.rgb, W);\n"
    "   fragColor = vec4(vec3(luminance), texColor.a);\n"
    "}\n";
    
const char* invertFs =
    "#version 300 es\n"
    "precision lowp float;\n"
    "in vec2 v_texcoord;\n"
    "uniform sampler2D u_texture;\n"
    "layout(location=0) out vec4 fragColor;\n"
    "void main() {\n"
    "  lowp vec4 textureColor = texture(u_texture, v_texcoord);\n"
    "  fragColor = vec4((1.0 - textureColor.rgb), textureColor.w);\n"
    "}\n";

const char* kuwaharaFs =
    "#version 300 es\n"
    "precision highp float;\n"
    "in vec2 v_texcoord;\n"
    "uniform sampler2D u_texture;\n"
    "uniform int radius;\n"
    "const vec2 src_size = vec2 (1.0 / 768.0, 1.0 / 1024.0);\n"
    "layout(location=0) out vec4 fragColor;\n"
    "void main() {\n"
    "  vec2 uv = v_texcoord;\n"
    "  float n = float((radius + 1) * (radius + 1));\n"
    "  int i; int j;\n"
    "  vec3 m0 = vec3(0.0); vec3 m1 = vec3(0.0); vec3 m2 = vec3(0.0); vec3 m3 = vec3(0.0);\n"
    "  vec3 s0 = vec3(0.0); vec3 s1 = vec3(0.0); vec3 s2 = vec3(0.0); vec3 s3 = vec3(0.0);\n"
    "  vec3 c;\n"
    "  for (j = -radius; j <= 0; ++j)  {\n"
    "    for (i = -radius; i <= 0; ++i)  {\n"
    "      c = texture(u_texture, uv + vec2(i,j) * src_size).rgb;\n"
    "      m0 += c;\n"
    "      s0 += c * c;\n"
    "    }\n"
    "  }\n"
    "  for (j = -radius; j <= 0; ++j)  {\n"
    "    for (i = 0; i <= radius; ++i)  {\n"
    "      c = texture(u_texture, uv + vec2(i,j) * src_size).rgb;\n"
    "      m1 += c;\n"
    "      s1 += c * c;\n"
    "    }\n"
    "  }\n"
    "  for (j = 0; j <= radius; ++j)  {\n"
    "    for (i = 0; i <= radius; ++i)  {\n"
    "      c = texture(u_texture, uv + vec2(i,j) * src_size).rgb;\n"
    "      m2 += c;\n"
    "      s2 += c * c;\n"
    "    }\n"
    "  }\n"
    "  for (j = 0; j <= radius; ++j)  {\n"
    "    for (i = -radius; i <= 0; ++i)  {\n"
    "      c = texture(u_texture, uv + vec2(i,j) * src_size).rgb;\n"
    "      m3 += c;\n"
    "      s3 += c * c;\n"
    "    }\n"
    "  }\n"
    "  float min_sigma2 = 1e+2;\n"
    "  m0 /= n;\n"
    "  s0 = abs(s0 / n - m0 * m0);\n"
    "  float sigma2 = s0.r + s0.g + s0.b;\n"
    "  if (sigma2 < min_sigma2) {\n"
    "    min_sigma2 = sigma2;\n"
    "    fragColor = vec4(m0, 1.0);\n"
    "  }\n"
    "  m1 /= n;\n"
    "  s1 = abs(s1 / n - m1 * m1);\n"
    "  sigma2 = s1.r + s1.g + s1.b;\n"
    "  if (sigma2 < min_sigma2) {\n"
    "    min_sigma2 = sigma2;\n"
    "    fragColor = vec4(m1, 1.0);\n"
    "  }\n"
    "  m2 /= n;\n"
    "  s2 = abs(s2 / n - m2 * m2);\n"
    "  sigma2 = s2.r + s2.g + s2.b;\n"
    "  if (sigma2 < min_sigma2) {\n"
    "    min_sigma2 = sigma2;\n"
    "    fragColor = vec4(m2, 1.0);\n"
    "  }\n"
    "  m3 /= n;\n"
    "  s3 = abs(s3 / n - m3 * m3);\n"
    "  sigma2 = s3.r + s3.g + s3.b;\n"
    "  if (sigma2 < min_sigma2) {\n"
    "    min_sigma2 = sigma2;\n"
    "    fragColor = vec4(m3, 1.0);\n"
    "  }\n"
    "}\n";

const char* pixFs =
    "#version 300 es\n"
    "precision highp float;\n"
    "in vec2 v_texcoord;\n"
    "uniform sampler2D u_texture;\n"
    "uniform float pixel;\n"
    "uniform float wFactor;\n"
    "uniform float hFactor;\n"
    "layout(location=0) out vec4 fragColor;\n"
    "void main() {\n"
    "  vec2 uv  = v_texcoord.xy;\n"
    "  float dx = pixel * wFactor;\n"
    "  float dy = pixel * hFactor;\n"
    "  vec2 coord = vec2(dx * floor(uv.x / dx), dy * floor(uv.y / dy));\n"
    "  vec3 tc = texture(u_texture, coord).xyz;\n"
    "  fragColor = vec4(tc, 1.0);\n"
    "}\n";

const char* sepiaFs =
    "#version 300 es\n"
    "precision lowp float;\n"
    "in vec2 v_texcoord;\n"
    "uniform sampler2D u_texture;\n"
    "const mat4 colorMatrix = mat4(0.3588, 0.7044, 0.1368, 0.0, 0.2990, 0.5870, "
    "0.1140, 0.0, 0.2392, 0.4696, 0.0912, 0.0, 0.0, 0.0, 0.0, 1.0);\n"
    "uniform float intensity;\n"
    "layout(location=0) out vec4 fragColor;\n"
    "void main() {\n"
    "    vec4 textureColor = texture(u_texture, v_texcoord);\n"
    "    vec4 outputColor = textureColor * colorMatrix;   \n"
    "    fragColor = (intensity * outputColor) + ((1.0 - intensity) * textureColor);\n"
    "}\n";

const char* sketchVs =
    "#version 300 es\n"
    "in vec4 a_position;\n"
    "in vec2 a_texcoord;\n"
    "uniform highp float texelWidth; \n"
    "uniform highp float texelHeight; \n"
    "out vec2 textureCoordinate;\n"
    "out vec2 leftTextureCoordinatecj;\n"
    "out vec2 rightTextureCoordinate;\n"
    "out vec2 topTextureCoordinate;\n"
    "out vec2 topLeftTextureCoordinatecj;\n"
    "out vec2 topRightTextureCoordinate;\n"
    "out vec2 bottomTextureCoordinate;\n"
    "out vec2 bottomLeftTextureCoordinatecj;\n"
    "out vec2 bottomRightTextureCoordinate;\n"
    "void main() {\n"
    "  gl_Position = a_position;\n"
    "  vec2 widthStep = vec2(texelWidth, 0.0);\n"
    "  vec2 heightStep = vec2(0.0, texelHeight);\n"
    "  vec2 widthHeightStep = vec2(texelWidth, texelHeight);\n"
    "  vec2 widthNegativeHeightStep = vec2(texelWidth, -texelHeight);\n"
    "  textureCoordinate = a_texcoord;\n"
    "  leftTextureCoordinatecj = a_texcoord - widthStep;\n"
    "  rightTextureCoordinate = a_texcoord + widthStep;\n"
    "  topTextureCoordinate = a_texcoord - heightStep;\n"
    "  topLeftTextureCoordinatecj = a_texcoord - widthHeightStep;\n"
    "  topRightTextureCoordinate = a_texcoord + widthNegativeHeightStep;\n"
    "  bottomTextureCoordinate = a_texcoord + heightStep;\n"
    "  bottomLeftTextureCoordinatecj = a_texcoord - widthNegativeHeightStep;\n"
    "  bottomRightTextureCoordinate = a_texcoord + widthHeightStep;\n"
    "}\n";

const char* sketchFs =
    "#version 300 es\n"
    "precision highp float;\n"
    "in vec2 textureCoordinate;\n"
    "in vec2 leftTextureCoordinatecj;\n"
    "in vec2 rightTextureCoordinate;\n"
    "in vec2 topTextureCoordinate;\n"
    "in vec2 topLeftTextureCoordinatecj;\n"
    "in vec2 topRightTextureCoordinate;\n"
    "in vec2 bottomTextureCoordinate;\n"
    "in vec2 bottomLeftTextureCoordinatecj;\n"
    "in vec2 bottomRightTextureCoordinate;\n"
    "uniform sampler2D u_texture;\n"
    "const vec3 W = vec3(0.2125, 0.7154, 0.0721);\n"
    "layout(location=0) out vec4 fragColor;\n"
    "void main() {\n"
    "  float bottomLeftIntensity = dot(texture(u_texture, bottomLeftTextureCoordinatecj).rgb, W);\n"
    "  float topRightIntensity = dot(texture(u_texture, topRightTextureCoordinate).rgb, W);\n"
    "  float topLeftIntensity = dot(texture(u_texture, topLeftTextureCoordinatecj).rgb, W);\n"
    "  float bottomRightIntensity = dot(texture(u_texture, bottomRightTextureCoordinate).rgb, W);\n"
    "  float leftIntensity = dot(texture(u_texture, leftTextureCoordinatecj).rgb, W);\n"
    "  float rightIntensity = dot(texture(u_texture, rightTextureCoordinate).rgb, W);\n"
    "  float bottomIntensity = dot(texture(u_texture, bottomTextureCoordinate).rgb, W);\n"
    "  float topIntensity = dot(texture(u_texture, topTextureCoordinate).rgb, W);\n"
    "  float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + "
    "bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;\n"
    "  float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + "
    "bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;\n"
    "  float mag = 1.0 - length(vec2(h, v));\n"
    "  fragColor = vec4(vec3(mag), 1.0);\n"
    "}\n";

const char* swirlFs =
    "#version 300 es\n"
    "precision lowp float;\n"
    "in vec2 v_texcoord;\n"
    "uniform sampler2D u_texture;\n"
    "uniform float radius;\n"
    "uniform float angle;\n"
    "uniform vec2 center;\n"
    "layout(location=0) out vec4 fragColor;\n"
    "void main() {\n"
    "  vec2 textureCoordinateToUse = v_texcoord;\n"
    "  float dist = distance(center, v_texcoord);\n"
    "  if (dist < radius) {\n"
    "    textureCoordinateToUse -= center;\n"
    "    float percent = (radius - dist) / radius;\n"
    "    float theta = percent * percent * angle * 8.0;\n"
    "    float s = sin(theta);\n"
    "    float c = cos(theta);\n"
    "    textureCoordinateToUse = vec2(dot(textureCoordinateToUse, vec2(c, -s)), "
    "dot(textureCoordinateToUse, vec2(s, c)));\n"
    "    textureCoordinateToUse += center;\n"
    "  }\n"
    "  fragColor = texture(u_texture, textureCoordinateToUse);\n"
    "}\n";

const char* toonVs =
    "#version 300 es\n"
    "in vec4 a_position;\n"
    "in vec2 a_texcoord;\n"
    "uniform float texelWidth;\n"
    "uniform float texelHeight;\n"
    "out vec2 textureCoordinate;\n"
    "out vec2 leftTextureCoordinate;\n"
    "out vec2 rightTextureCoordinate;\n"
    "out vec2 topTextureCoordinate;\n"
    "out vec2 topLeftTextureCoordinate;\n"
    "out vec2 topRightTextureCoordinate;\n"
    "out vec2 bottomTextureCoordinate;\n"
    "out vec2 bottomLeftTextureCoordinate;\n"
    "out vec2 bottomRightTextureCoordinate;\n"
    "void main() {\n"
    "  gl_Position = a_position;\n"
    "  vec2 widthStep = vec2(texelWidth, 0.0);\n"
    "  vec2 heightStep = vec2(0.0, texelHeight);\n"
    "  vec2 widthHeightStep = vec2(texelWidth, texelHeight);\n"
    "  vec2 widthNegativeHeightStep = vec2(texelWidth, -texelHeight);\n"
    "  textureCoordinate = a_texcoord;\n"
    "  leftTextureCoordinate = a_texcoord - widthStep;\n"
    "  rightTextureCoordinate = a_texcoord + widthStep;\n"
    "  topTextureCoordinate = a_texcoord - heightStep;\n"
    "  topLeftTextureCoordinate = a_texcoord - widthHeightStep;\n"
    "  topRightTextureCoordinate = a_texcoord + widthNegativeHeightStep;\n"
    "  bottomTextureCoordinate = a_texcoord + heightStep;\n"
    "  bottomLeftTextureCoordinate = a_texcoord - widthNegativeHeightStep;\n"
    "  bottomRightTextureCoordinate = a_texcoord + widthHeightStep;\n"
    "}\n";

const char* toonFs =
    "#version 300 es\n"
    "precision highp float;\n"
    "in vec2 textureCoordinate;\n"
    "in vec2 leftTextureCoordinate;\n"
    "in vec2 rightTextureCoordinate;\n"
    "in vec2 topTextureCoordinate;\n"
    "in vec2 topLeftTextureCoordinate;\n"
    "in vec2 topRightTextureCoordinate;\n"
    "in vec2 bottomTextureCoordinate;\n"
    "in vec2 bottomLeftTextureCoordinate;\n"
    "in vec2 bottomRightTextureCoordinate;\n"
    "uniform sampler2D u_texture;\n"
    "uniform float threshold;\n"
    "uniform float quantizationLevels;\n"
    "layout(location=0) out vec4 fragColor;\n"
    "void main() {\n"
    "  vec4 textureColor = texture(u_texture, textureCoordinate);\n"
    "  float bottomLeftIntensity = texture(u_texture, bottomLeftTextureCoordinate).r;\n"
    "  float topRightIntensity = texture(u_texture, topRightTextureCoordinate).r;\n"
    "  float topLeftIntensity = texture(u_texture, topLeftTextureCoordinate).r;\n"
    "  float bottomRightIntensity = texture(u_texture, bottomRightTextureCoordinate).r;\n"
    "  float leftIntensity = texture(u_texture, leftTextureCoordinate).r;\n"
    "  float rightIntensity = texture(u_texture, rightTextureCoordinate).r;\n"
    "  float bottomIntensity = texture(u_texture, bottomTextureCoordinate).r;\n"
    "  float topIntensity = texture(u_texture, topTextureCoordinate).r;\n"
    "  float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + "
    "bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;\n"
    "  float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + "
    "bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;\n"
    "  float mag = length(vec2(h, v));\n"
    "  vec3 posterizedImageColor = floor((textureColor.rgb * quantizationLevels) + 0.5) / quantizationLevels;\n"
    "  float thresholdTest = 1.0 - step(threshold, mag);\n"
    "  fragColor = vec4(posterizedImageColor * thresholdTest, textureColor.a);\n"
    "}\n";

const char* vigFs =
    "#version 300 es\n"
    "precision lowp float;\n"
    "in vec2 v_texcoord;\n"
    "uniform sampler2D u_texture;\n"
    "uniform vec2 vignetteCenter;\n"
    "uniform vec3 vignetteColor;\n"
    "uniform float vignetteStart;\n"
    "uniform float vignetteEnd;\n"
    "layout(location=0) out vec4 fragColor;\n"
    "void main() {\n"
    "  vec3 rgb = texture(u_texture, v_texcoord).rgb;\n"
    "  float d = distance(v_texcoord, vec2(vignetteCenter.x, vignetteCenter.y));\n"
    "  float percent = smoothstep(vignetteStart, vignetteEnd, d);\n"
    "  fragColor = vec4(mix(rgb.x, vignetteColor.x, percent), mix(rgb.y, vignetteColor.y, percent), "
    "mix(rgb.z, vignetteColor.z, percent), 1.0);\n"
    "}\n";

    const char* circlecropFs =
    "#version 300 es\n"
    "precision lowp float;\n"
    "in vec2 v_texcoord;\n"
    "uniform sampler2D u_texture;\n"
    "uniform vec2 resolution;\n"
    "layout(location=0) out vec4 fragColor;\n"
    "void main() {\n"
    "  vec4 clr = texture(u_texture, v_texcoord);\n"
    "  vec2 center = vec2(0.5, 0.5);\n"
    "  center.x = center.x * (resolution.x / resolution.y);\n"
    "  vec2 texpos = v_texcoord;\n"
    "  texpos.x = texpos.x * (resolution.x / resolution.y);\n"
    "  float dist = distance(center, texpos);\n"
    "  if (dist <= 0.5) {\n"
    "    fragColor = clr;\n"
    "  } else {\n"
    "    fragColor = vec4(0.0, 0.0, 0.0, 0.0);\n"
    "  }\n"
    "}\n";

// 1 bl, 2 br, 3 tl, 4 tr
const char* roundedcornersFs =
    "#version 300 es\n"
    "precision lowp float;\n"
    "in vec2 v_texcoord;\n"
    "uniform sampler2D u_texture;\n"
    "uniform vec2 resolution;\n"
    "uniform float radius1;\n"
    "uniform float radius2;\n"
    "uniform float radius3;\n"
    "uniform float radius4;\n"
    "layout(location=0) out vec4 fragColor;\n"
    "void main() {\n"
    "  vec4 clr = texture(u_texture, v_texcoord);\n"
    "  vec2 ratio = vec2(resolution.x / resolution.y, 1.0);\n"
    "  vec2 xy = v_texcoord * ratio;\n"
    "  float r1 = radius1 / resolution.y;\n"
    "  float r2 = radius2 / resolution.y;\n"
    "  float r3 = radius3 / resolution.y;\n"
    "  float r4 = radius4 / resolution.y;\n"
    "  vec2 c1 = vec2(r1, r1);\n"
    "  vec2 c2 = vec2(ratio.x - r2, r2);\n"
    "  vec2 c3 = vec2(r3, ratio.y - r3);\n"
    "  vec2 c4 = vec2(ratio.x - r4, ratio.y - r4);\n"
    "  if (radius1 > 0.0 && xy.x < c1.x && xy.y < c1.y && distance(c1, xy) > r1) {\n"
    "    fragColor = vec4(0.0, 0.0, 0.0, 0.0);\n"
    "  } else if (radius2 > 0.0 && xy.x > c2.x && xy.y < c2.y && distance(c2, xy) > r2) {\n"
    "    fragColor = vec4(0.0, 0.0, 0.0, 0.0);\n"
    "  } else if (radius3 > 0.0 && xy.x < c3.x && xy.y > c3.y && distance(c3, xy) > r3) {\n"
    "    fragColor = vec4(0.0, 0.0, 0.0, 0.0);\n"
    "  } else if (radius4 > 0.0 && xy.x > c4.x && xy.y > c4.y && distance(c4, xy) > r4) {\n"
    "    fragColor = vec4(0.0, 0.0, 0.0, 0.0);\n"
    "  } else {\n"
    "    fragColor = clr;\n"
    "  }\n"
    "}\n";

    const char* fastblurFs =
    "#version 300 es\n"
    "precision highp float;\n"
    "in vec2 v_texcoord;\n"
    "uniform sampler2D u_texture;\n"
    "uniform int r;\n"
    "layout(location=0) out vec4 fragColor;\n"
    "void main() {\n"
    "  float r1 = float(r) + 1.0;\n"
    "  float rbsSum = 0.0;\n"
    "  ivec2 texSz = textureSize(u_texture, 0);\n"
    "  vec2 texelSz = 1.0 / vec2(texSz);\n"
    "  vec4 clrSum = vec4(0.0, 0.0, 0.0, 0.0);\n"
    "  for (int y = -r; y <= r; y++) {\n"
    "    float fy = float (y);\n"
    "    float rbsY = r1 - abs(fy);\n"
    "    for (int x = -r; x <=r; x++) {\n"
    "      float fx = float(x);\n"
    "      float rbs = (r1 - abs(fx)) * rbsY;\n"
    "      rbs *= rbs;\n"
    "      vec4 clr = texture(u_texture, v_texcoord + vec2(fx * texelSz.x, fy * texelSz.y));\n"
    "      clrSum += clr * vec4(rbs);\n"
    "      rbsSum += rbs;\n"
    "    }\n"
    "  }\n"
    "  fragColor = clrSum / rbsSum;\n"
    "}\n";
    
#endif